home *** CD-ROM | disk | FTP | other *** search
- /*
- * gears.c - Create a set of gears. Each gear face has 144 vertices, and
- * contains concavities. Note that the first 3 vertices of all polygons
- * define the two edges of a convex section of the polygon. Background
- * square floor is reflective. Some gears are clipped.
- * Five light sources.
- *
- * Version: 2.2 (11/17/87)
- * Author: Eric Haines, 3D/Eye, Inc.
- *
- * SIZE_FACTOR determines the number of polygons output.
- * Total gears = SF**3: concave polygons = 2 * SF**3
- * rectangles = 4*TEETH * SF**3
- *
- * SIZE_FACTOR # gears # gear faces # rectangles
- * 1 1 2 144
- * 2 8 16 1152
- * 3 27 54 3888
- * 4 64 128 9216
- */
-
- #include <stdio.h>
- #include <math.h>
- #ifdef MAC
- #include <console.h>
- #endif
- #include "def.h"
- #include "lib.h"
-
- #define SIZE_FACTOR 2
-
- /* define number of teeth on a gear - must be a multiple of 4 */
- #define TEETH 32
- /* define ratio of radius taken up by teeth and the gear thickness */
- #define EDGE_RATIO 0.1
- #define DEPTH_RATIO 0.1
-
- /* Create gear tooth */
- static void
- create_tooth(double gear_angle, double tooth_angle,
- COORD4 *center, COORD4 *outer_pt,
- COORD4 *inner_pt, COORD4 *edge_pts)
- {
- MATRIX mx ;
-
-
- lib_create_rotate_matrix( mx
- , Z_AXIS
- , gear_angle - 0.19 * tooth_angle ) ;
- lib_transform_coord( &edge_pts[0], outer_pt, mx ) ;
- ADD2_COORD( edge_pts[0], *center ) ;
- lib_create_rotate_matrix( mx
- , Z_AXIS
- , gear_angle + 0.19 * tooth_angle ) ;
- lib_transform_coord( &edge_pts[1], outer_pt, mx ) ;
- ADD2_COORD( edge_pts[1], *center ) ;
- lib_create_rotate_matrix( mx
- , Z_AXIS
- , gear_angle + 0.3 * tooth_angle ) ;
- lib_transform_coord( &edge_pts[2], inner_pt, mx ) ;
- ADD2_COORD( edge_pts[2], *center ) ;
- lib_create_rotate_matrix( mx
- , Z_AXIS
- , gear_angle + 0.7 * tooth_angle ) ;
- lib_transform_coord( &edge_pts[3], inner_pt, mx ) ;
- ADD2_COORD( edge_pts[3], *center ) ;
- }
-
-
- /* Create gear */
- static void
- create_gear(COORD4 *center, double offset_angle, double outer_radius,
- double inner_radius, double thickness,
- char *txname)
- {
- COORD4 side_pts[4], gear_pts[4*TEETH], outer_pt, inner_pt ;
- long next_side, num_side, num_teeth ;
- double gear_angle, tooth_angle ;
-
-
- outer_pt.x = outer_radius ;
- outer_pt.y = 0.0 ;
- outer_pt.z = 0.0 ;
- outer_pt.w = 1.0 ;
- inner_pt.x = inner_radius ;
- inner_pt.y = 0.0 ;
- inner_pt.z = 0.0 ;
- inner_pt.w = 1.0 ;
-
- tooth_angle = 2.0 * PI / (double)TEETH ;
-
- /* output gear top */
- for ( num_teeth = 0 ; num_teeth < TEETH ; ++num_teeth ) {
- gear_angle = offset_angle +
- 2.0 * PI * (double)num_teeth / (double)TEETH ;
- create_tooth( gear_angle
- , tooth_angle
- , center
- , &outer_pt
- , &inner_pt
- , &gear_pts[num_teeth*4]
- ) ;
- }
- lib_output_polygon(4*TEETH, gear_pts, txname);
-
- /* output teeth */
- for ( num_side = 0 ; num_side < 4 * TEETH ; ++num_side ) {
- next_side = ( num_side + 1 ) % ( 4 * TEETH ) ;
- COPY_COORD( side_pts[0], gear_pts[num_side] ) ;
- COPY_COORD( side_pts[1], gear_pts[num_side] ) ;
- side_pts[1].z -= thickness ;
- COPY_COORD( side_pts[2], gear_pts[next_side] ) ;
- side_pts[2].z -= thickness ;
- COPY_COORD( side_pts[3], gear_pts[next_side] ) ;
- lib_output_polygon(4, side_pts, txname);
- }
-
- /* output gear bottom */
- outer_pt.z = inner_pt.z = -thickness ;
- for ( num_teeth = 0 ; num_teeth < TEETH ; ++num_teeth ) {
- gear_angle = offset_angle -
- 2.0 * PI * (double)num_teeth / (double)TEETH ;
- create_tooth( gear_angle
- , -tooth_angle
- , center
- , &outer_pt
- , &inner_pt
- , &gear_pts[num_teeth*4]
- ) ;
- }
- lib_output_polygon(4*TEETH, gear_pts, txname);
- }
-
- void
- main(int argc, char *argv[])
- {
- COORD4 back_color, gear_color ;
- COORD4 center_pt, floor[4], light, offset, zero_pt ;
- COORD4 from, at, up, dir;
- double angle, color_scale, outer_radius, thickness ;
- long ix, iy, iz ;
- char *txname;
-
- #ifdef MAC
- argc = ccommand(&argv);
- #endif
-
- /* output viewpoint */
- SET_COORD( from, -1.1, -2.1, 2.6 ) ;
- SET_COORD( at, 0.0, 0.0, 0.0 ) ;
- SET_COORD( up, 0.0, 0.0, 1.0 ) ;
- lib_output_viewpoint( &from, &at, &up, 45.0, 1.0, 1.0, 256, 256);
-
- /* output background color - UNC sky blue */
- SET_COORD( back_color, 0.078, 0.361, 0.753 ) ;
- lib_output_background_color( &back_color ) ;
-
- /* output light sources */
- SET_COORD( light, 2.0, 4.0, 4.0 ) ;
- lib_output_light( &light ) ;
- SET_COORD( light, -2.0, 4.0, 3.0 ) ;
- lib_output_light( &light ) ;
- SET_COORD( light, 2.0, -2.5, 2.5 ) ;
- lib_output_light( &light ) ;
- SET_COORD( light, -1.0, -4.0, 2.0 ) ;
- lib_output_light( &light ) ;
- /* just behind the eye */
- SET_COORD( light, -1.111, -2.121, 2.626 ) ;
- lib_output_light( &light ) ;
-
- /* Output bounding slabs oriented along the coordinate axes */
- SET_COORD(dir, 1.0, 0.0, 0.0);
- lib_output_bounding_slab(&dir);
- SET_COORD(dir, 0.0, 1.0, 0.0);
- lib_output_bounding_slab(&dir);
- SET_COORD(dir, 0.0, 0.0, 1.0);
- lib_output_bounding_slab(&dir);
-
- /* output floor polygon - off white */
- SET_COORD( back_color, 1.0, 0.85, 0.7 ) ;
- txname = lib_output_color(&back_color, 0.1, 0.75, 0.25, 25.0, 0.0, 0.0, 0.0);
- SET_COORD( floor[0], 2.0, 2.0, 0.0 ) ;
- SET_COORD( floor[1], -2.0, 2.0, 0.0 ) ;
- SET_COORD( floor[2], -2.0, -2.0, 0.0 ) ;
- SET_COORD( floor[3], 2.0, -2.0, 0.0 ) ;
- lib_output_polygon(4, floor, txname);
-
- outer_radius=1.0/((double)SIZE_FACTOR-(double)(SIZE_FACTOR-1)*EDGE_RATIO/2.0);
- /* calculate first gear center */
- zero_pt.x = zero_pt.y = -1.0 + outer_radius ;
- zero_pt.z = 1.0 ;
- /* calculate offset */
- offset.x = offset.y = outer_radius * ( 2.0 - EDGE_RATIO ) ;
- offset.z = -1.0 / (double)SIZE_FACTOR ;
-
- /* create gears */
- for ( iz = 0 ; iz < SIZE_FACTOR ; ++iz ) {
- center_pt.z = zero_pt.z + (double)iz * offset.z ;
- for ( iy = 0 ; iy < SIZE_FACTOR ; ++iy ) {
- center_pt.y = zero_pt.y + (double)iy * offset.y ;
- for ( ix = 0 ; ix < SIZE_FACTOR ; ++ix ) {
- center_pt.x = zero_pt.x + (double)ix * offset.x ;
-
- /* output pseudo-random gear color */
- SET_COORD(gear_color,
- 0.01 + FRACTION( (double)(ix*3+iy*2+iz+1)*5.0/7.0 ),
- 0.01 + FRACTION( (double)(iy*3+iz*2+ix+1)*3.0/7.0 ),
- 0.01 + FRACTION( (double)(iz*3+ix*2+iy+1)*2.0/7.0 ));
- color_scale = MAX3( gear_color.x, gear_color.y, gear_color.z );
- gear_color.x /= color_scale ;
- gear_color.y /= color_scale ;
- gear_color.z /= color_scale ;
- if ((ix*4 + iy*2 + iz ) % 5 == 0)
- txname = lib_output_color(&gear_color, 0.1, 0.75, 0.25, 50.0,
- 0.0, 0.95, 1.1);
- else
- txname = lib_output_color(&gear_color, 0.2, 0.8, 0.0, 0.0,
- 0.0, 0.0, 0.0);
-
-
- /* output gear */
- angle = PI * (double)( (ix+iy+iz) % 2 ) / (double)(TEETH);
- thickness = MIN( DEPTH_RATIO, 1.0 / ( 2.0 * (double)SIZE_FACTOR));
- create_gear(¢er_pt, angle, outer_radius,
- (1.0 - EDGE_RATIO) * outer_radius,
- thickness, txname);
- }
- }
- }
- }
-